/*
   Copyright (c) 2005 Lucas Mello Schnorr <schnorr@gmail.com>
   
   This file is part of DIMVisual.
   
   DIMVisual is free software; you can redistribute it and/or modify it under
   the terms of the GNU Lesser General Public License as published by the
   Free Software Foundation; either version 2 of the License, or (at your
   option) any later version.
   
   DIMVisual is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   for more details.
   
   You should have received a copy of the GNU Lesser General Public License
   along with DIMVisual; if not, write to the Free Software Foundation, Inc.,
   59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include "MPIRASTROConverter.h"

static int size = -1;

@implementation MPIRASTROConverter (All)
- (id) convertEventAll: (MPIRASTROEvent *) event
{
	NSMutableArray *ret = nil;
	NSString *container;
	int type,i;

	if (alltoall == nil){
		alltoall = [[AllToOne alloc] init];
	}
	if (alltoallv == nil){
		alltoallv = [[AllToOne alloc] init];
	}
	
	
	ret = [[NSMutableArray alloc] init];

	container = [provider identifierForEntity: 
		[NSArray arrayWithObjects: @"Machine", @"Thread", nil]
				ids:
		[NSArray arrayWithObjects: [event machine], [event thread], nil]];

	if (container == nil){
		[ret release];
		return nil;
	}

	int etype = atoi ([[event type] cString]);

	
/*******************************************************************************
	 * MPI_ALLTOALL
*******************************************************************************/
	if (etype == MPI_ALLTOALL_IN){
		if (size == -1){
			size = atoi([[event int32AtIndex: 1] cString]);
			for (i = 0; i < size; i++){
				AllToOne *x = [[AllToOne alloc] init];
				[alltoall addObject: x];
				[x release];
			}
		}
		for (i = 0; i < size; i++){
			[[alltoall objectAtIndex:i] memberEntering: container
				andEventNode: [event node]
				andEventTime: [event time]
				andRootNode: [NSString stringWithFormat:@"%d",i]
				andCommSize: [event int32AtIndex: 1]];
		}
		[ret addObject: [self addPajeSetState: @"MPI_ALLTOALL" time: [event time] container: container]];
	}else if (etype == MPI_ALLTOALL_OUT){
		for (i = 0; i < size; i++){
			[ret addObjectsFromArray:
				[[alltoall objectAtIndex:i]
					memberExiting: container
					andEventTime: [event time]
					andOperationName: @"alltoall"
					andProvider: provider]];
		}
		[ret addObject: [self addPajeSetState: @"running" time: [event time] container: container]];

/*******************************************************************************
	 * MPI_ALLTOALLV
*******************************************************************************/
	}else if (etype == MPI_ALLTOALLV_IN){
		if (size == -1){
			size = atoi([[event int32AtIndex: 1] cString]);
			for (i = 0; i < size; i++){
				AllToOne *x = [[AllToOne alloc] init];
				[alltoallv addObject: x];
				[x release];
			}
		}
		for (i = 0; i < size; i++){
			[[alltoallv objectAtIndex:i] memberEntering: container
				andEventNode: [event node]
				andEventTime: [event time]
				andRootNode: [NSString stringWithFormat:@"%d",i]
				andCommSize: [event int32AtIndex: 1]];
		}
		[ret addObject: [self addPajeSetState: @"MPI_ALLTOALLV" time: [event time] container: container]];
	}else if (etype == MPI_ALLTOALLV_OUT){
		for (i = 0; i < size; i++){
			[ret addObjectsFromArray:
				[[alltoallv objectAtIndex:i]
					memberExiting: container
					andEventTime: [event time]
					andOperationName: @"alltoallv"
					andProvider: provider]];
		}
		[ret addObject: [self addPajeSetState: @"running" time: [event time] container: container]];

/*******************************************************************************
	 * MPI_BARRIER
*******************************************************************************/
	}else if (etype == MPI_BARRIER_IN){
		[ret addObject: [self addPajeSetState: @"MPI_BARRIER" time: [event time] container: container]];
	}else if (etype == MPI_BARRIER_OUT){
		[ret addObject: [self addPajeSetState: @"running" time: [event time] container: container]];
	}

	[ret autorelease];
	return ret;
}
@end
